package com.hua.util;

import android.os.Handler;
import android.os.Looper;
import android.util.Log;

import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Callable;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 蒋剑华
 * 线程池单例工具类（全局统一管理，避免多线程池资源浪费）
 * 核心优化：动态适配 CPU 核心数、有限任务队列、自定义线程名称、安全拒绝策略、主线程切换
 */
public class CommThreadPoolUtils {
    private static final String TAG = "<---HUA--->";
    // 单例实例（volatile 禁止指令重排，保证线程安全）
    private static volatile CommThreadPoolUtils sInstance;
    // 核心线程池（底层实现）
    private ThreadPoolExecutor mThreadPool;
    // 主线程 Handler（用于子线程切换到主线程）
    private Handler mMainHandler;

    // 私有构造器（禁止外部实例化）
    private CommThreadPoolUtils() {
        initThreadPool();
        initMainHandler();
    }


    /**
     * 获取单例实例（双重校验锁，线程安全）
     */
    public static CommThreadPoolUtils getInstance() {
        if (sInstance == null) {
            synchronized (CommThreadPoolUtils.class) {
                if (sInstance == null) {
                    sInstance = new CommThreadPoolUtils();
                }
            }
        }
        return sInstance;
    }

    /**
     * 初始化线程池（核心参数优化，适配 Android 场景）
     */
    private void initThreadPool() {
        // 1. 动态获取 CPU 核心数（充分利用多核性能，避免线程过多）
        int cpuCoreCount = Runtime.getRuntime().availableProcessors();
        // 2. 核心参数配置（根据实际需求调整）
        int corePoolSize = cpuCoreCount; // 核心线程数 = CPU核心数（常驻线程）
        int maximumPoolSize = cpuCoreCount * 2; // 最大线程数 = 核心数 * 2（避免线程爆炸）
        long keepAliveTime = 30; // 临时线程空闲 30 秒销毁（节省资源）
        TimeUnit unit = TimeUnit.SECONDS;

        // 3. 任务队列（容量10，避免无界队列堆积导致 OOM）
        BlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>(10);

        // 4. 线程工厂（自定义线程名称，方便日志排查；设置合理优先级）
        ThreadFactory threadFactory = new ThreadFactory() {
            private final AtomicInteger threadCount = new AtomicInteger(0); // 原子类计数，线程安全

            @Override
            public Thread newThread(Runnable r) {
                Thread thread = new Thread(r, "AppThreadPool-" + threadCount.incrementAndGet());
                thread.setPriority(Thread.NORM_PRIORITY); // 正常优先级（避免影响 UI 线程）
                thread.setDaemon(false); // 非守护线程（避免主线程退出时被强制中断）
                return thread;
            }
        };


        // 6. 创建线程池
        mThreadPool = new ThreadPoolExecutor(
                corePoolSize,
                maximumPoolSize,
                keepAliveTime,
                unit,
                workQueue,
                threadFactory
        );
    }

    /**
     * 初始化主线程 Handler（用于切换到主线程更新 UI）
     */
    private void initMainHandler() {
        // 绑定主线程 Looper
        mMainHandler = new Handler(Looper.getMainLooper());
    }

    // -------------------------- 对外提供的 API --------------------------
    /**
     * 提交无返回值任务（子线程执行）
     * @param task 耗时任务（如网络请求、文件读写）
     */
    public void execute(Runnable task) {
        if (task == null) return;
        try {
            mThreadPool.execute(task);
        } catch (Exception e) {
            Log.e(TAG, "执行任务失败：", e);
        }
    }

    /**
     * 提交有返回值任务（子线程执行，通过 Callback 获取结果）
     * @param task 有返回值的任务
     * @param callback 结果回调（主线程执行，可直接更新 UI）
     * @param <T> 返回值类型
     */
    public <T> void submit(Callable<T> task, ResultCallback<T> callback) {
        if (task == null || callback == null) return;

        mThreadPool.submit(() -> {
            try {
                // 子线程执行任务，获取结果
                T result = task.call();
                // 切换到主线程回调成功结果
                postToMainThread(() -> callback.onSuccess(result));
            } catch (Exception e) {
                // 切换到主线程回调失败结果
                postToMainThread(() -> callback.onFailure(e));
            }
        });
    }

    /**
     * 提交延迟任务（子线程执行）
     * @param task 耗时任务
     * @param delayMillis 延迟时间（毫秒）
     */
    public void executeDelayed(Runnable task, long delayMillis) {
        if (task == null || delayMillis < 0) return;
        mMainHandler.postDelayed(() -> execute(task), delayMillis);
    }

    /**
     * 切换到主线程执行任务（如更新 UI）
     * @param task 主线程任务（如刷新控件、弹 Toast）
     */
    public void postToMainThread(Runnable task) {
        if (task == null) return;
        // 判断当前是否在主线程，避免不必要的 Handler 发送
        if (Looper.myLooper() == Looper.getMainLooper()) {
            task.run();
        } else {
            mMainHandler.post(task);
        }
    }

    /**
     * 切换到主线程执行延迟任务
     * @param task 主线程任务
     * @param delayMillis 延迟时间（毫秒）
     */
    public void postToMainThreadDelayed(Runnable task, long delayMillis) {
        if (task == null || delayMillis < 0) return;
        mMainHandler.postDelayed(task, delayMillis);
    }

    /**
     * 移除主线程延迟任务（如页面销毁时取消未执行的 UI 任务）
     * @param task 要移除的任务（需保持任务实例一致）
     */
    public void removeMainThreadTask(Runnable task) {
        if (task == null) return;
        mMainHandler.removeCallbacks(task);
    }

    /**
     * 关闭线程池（App 退出时调用，避免内存泄漏）
     * 等待现有任务执行完毕，不接受新任务
     */
    public void shutdown() {
        if (mThreadPool != null && !mThreadPool.isShutdown()) {
            mThreadPool.shutdown();
            Log.d(TAG, "线程池已关闭，等待现有任务执行完毕");
        }
    }

    /**
     * 立即关闭线程池（强制中断正在执行的任务）
     * 慎用！仅适合紧急退出场景
     */
    public void shutdownNow() {
        if (mThreadPool != null && !mThreadPool.isShutdown()) {
            mThreadPool.shutdownNow();
            Log.d(TAG, "线程池立即关闭，中断所有正在执行的任务");
        }
    }

    /**
     * 检查线程池是否已关闭
     */
    public boolean isShutdown() {
        return mThreadPool != null && mThreadPool.isShutdown();
    }

    // -------------------------- 结果回调接口 --------------------------
    /**
     * 有返回值任务的回调接口（主线程执行）
     * @param <T> 返回值类型
     */
    public interface ResultCallback<T> {
        /**
         * 任务执行成功
         * @param result 任务返回值
         */
        void onSuccess(T result);

        /**
         * 任务执行失败
         * @param e 异常信息
         */
        void onFailure(Exception e);
    }

    // -------------------------- 静态辅助方法（简化调用） --------------------------
    /**
     * 静态快捷调用：执行无返回值任务
     */
    public static void runOnSubThread(Runnable task) {
        getInstance().execute(task);
    }

    /**
     * 静态快捷调用：执行有返回值任务
     */
    public static <T> void runOnSubThread(Callable<T> task, ResultCallback<T> callback) {
        getInstance().submit(task, callback);
    }

    /**
     * 静态快捷调用：切换到主线程执行任务
     */
    public static void runOnMainThread(Runnable task) {
        getInstance().postToMainThread(task);
    }
}